﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;


namespace Boardgame
{
    public enum Player { White, Black }


    public class Square
    {
        protected Square ()
        { }

        static public readonly Square Empty = new Square();

        public bool IsOccupied
        { get { return this.GetType() != typeof (Square); } }

        public virtual bool IsOpponent (Player player) { return false; }
        public virtual bool NotPlayer (Player player) { return true; }
        public virtual bool IsPlayer (Player player) { return false; }

        public override string ToString ()
        { return "."; }
    }


    /// <summary>Represent the board as a two-dimensional array.</summary>
    /// <remarks>
    /// The board consists of a two-dimensional array of Squares. Each Square
    /// may be empty (a Square) or may be an instance of a subclass of Piece.
    /// </remarks>
    public class Board
    {
        internal Square[,] squares;

        // The board's dimensions, softcoded.
        public int SizeX { get { return squares.GetUpperBound (0) + 1; } }
        public int SizeY { get { return squares.GetUpperBound (1) + 1; } }

        public Square this[int cx, int cy]
        { get { return squares[cx, cy]; } }


        /// <summary>Create a new board.</summary>
        /// <remarks>This constructor contains the only hard-coded size of the board.</remarks>
        internal Board (int sizeX, int sizeY)
        {
            squares = new Square[sizeX, sizeY];
            Clear();
        }


        internal void Clear ()
        {
            for (int cx = 0; cx < SizeX; ++cx)
                for (int cy = 0; cy < SizeY; ++cy)
                    squares[cx, cy] = Square.Empty;
        }


        /// <summary>Produce a text representation of the current board.</summary>
        /// <remarks>
        /// The returned string is useful for bench testing and debugger visualization.
        /// It is not intended to be used for actual gameplay.
        /// </remarks>
        /// <returns>The current board as readable text.</returns>
        public override string ToString ()
        {
            var result = new StringBuilder (SizeX * 2 * SizeY);

            for (int cy = SizeY - 1; ; --cy)
            {
                for (int cx = 0; ; ++cx)
                {
                    result.Append (squares[cx, cy].ToString());

                    if (cx >= SizeX - 1)
                        break;

                    result.Append (' ');
                }

                if (cy <= 0)
                    return result.ToString();

                result.Append ('\n');
            }
        }
    }
}
